#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/time.h>
 
#include "data_type.h"
#include "alloc.h"
#include "memfunc.h"
#include "basefunc.h"
#include "struct_deal.h"
#include "crypto_func.h"
#include "memdb.h"
#include "message.h"
#include "ex_module.h"
#include "sys_func.h"
#include "integrity_report.h"
#include "system_entity.h"
#include "integrity_measure.h"
// add para lib_include
BYTE buffer[1024];
int integrity_report_init(void * sub_proc, void * para)
{
	int ret;
	// add yorself's module init func here
	return 0;
}
int integrity_report_start(void * sub_proc, void * para)
{
	int ret;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here
	usleep(1000*50);
	ret=proc_integrity_report(sub_proc,NULL);	

	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		ret=proc_integrity_report(sub_proc,recv_msg);	
	
	}
	return 0;
}

int proc_integrity_report(void * sub_proc,void * recv_msg)
{
	int ret=0;
	int count=0;
	RECORD(SYSTEM_ENTITY,UNIT_SET) * unitset;
	RECORD(INTEGRITY_COLLECT,UNITSET_MEASURE) * measure_value;
	DB_RECORD * record;
	void * send_msg;
	int i=0;

	unitset=memdb_get_first_record(TYPE_PAIR(SYSTEM_ENTITY,UNIT_SET));
	
	if(unitset!=NULL)
	{
		measure_value=Talloc(sizeof(*measure_value));
		if(measure_value == NULL)
			return -EINVAL;
//		Memcpy(measure_value->unitset_uuid,unitset->uuid,DIGEST_SIZE);	
		ret=measure_unitset(unitset,measure_value);

//		unitset=memdb_get_next_record(TYPE_PAIR(SYSTEM_ENTITY,UNIT_SET));
	}


	if(recv_msg==NULL)
	{
		send_msg=message_create(TYPE_PAIR(INTEGRITY_COLLECT,UNITSET_MEASURE),recv_msg);
		if(send_msg==NULL)
			return -EINVAL;
		message_add_record(send_msg,measure_value);
		ex_module_sendmsg(sub_proc,send_msg);
	}
	else
	{
		message_add_expand_data(recv_msg,TYPE_PAIR(INTEGRITY_COLLECT,UNITSET_MEASURE),measure_value);
		ex_module_sendmsg(sub_proc,recv_msg);
	}


	return count;
}


int measure_unitset(RECORD(SYSTEM_ENTITY,UNIT_SET) * unitset, RECORD(INTEGRITY_COLLECT,UNITSET_MEASURE) * measure_value)
{
	int ret;
	int i,count;
	int pathlen;
	DB_RECORD * record;
	measure_value->type=unitset->type;
	measure_value->num=unitset->num;	
	measure_value->measure_value=Talloc0(DIGEST_SIZE*measure_value->num);
	if(measure_value->measure_value ==NULL)
		return -ENOMEM;
	pathlen=Strlen(unitset->path);
	Memcpy(buffer,unitset->path,pathlen);
	buffer[pathlen++]='/';
	for(i=0;i<measure_value->num;i++)
	{
		Strcpy(buffer+pathlen,unitset->units+DIGEST_SIZE*3*i);
		ret=calculate_sm3(buffer,measure_value->measure_value+DIGEST_SIZE*i);
		if(ret<0)
		{
			printf("open file %s error!\n",buffer);
			return ret;
		}
	}	
	ret=calculate_context_sm3(measure_value->measure_value,DIGEST_SIZE*measure_value->num,measure_value->uuid);
	return i;
}
